<script setup lang="ts">
import { handleDelKey } from '@/utils';
import { searchConfig } from './config/search-config';
import { tableConfig } from './config/table-config';
import { editConfig } from './config/edit-config';
import { ProductionType } from '@/config';
import { Message } from '@/instance';
import { Plus, Delete } from '@element-plus/icons-vue';
import MaterialSettingModal from './dialog/MaterialSetting/index.vue';
import paramsStore from '@/store/modules/paramsStore';
import procurementUnit from '@/views/Base/MaterialsManagement/dialog/procurementUnit/index.vue';
import {
    doGetMaterialList,
    doGetMaterialSetting,
    doDelMaterial,
    doUpdateMaterial,
    doGetMaterialUnit
} from '@/api/base/materialsManagement';
import type { MaterialListInfo, MaterialSetting } from '@/api/base/materialsManagement/model/type';

defineOptions({
    name: 'MaterialsManagementList'
});

const router = useRouter();

const { handleAddData } = addDataStore();

const materialSettingList = ref<StandardOptions[]>([]);
const materialSettingRef = ref();
const editTableConfig = ref<any>(editConfig);

/**
 * 搜索模块
 */
const tableRef = ref<TableRef>();

/**
 * 删除模块
 */
const searchRef = ref<SearchRef>();
const selectIds = ref<number[]>([]);
const materialList = ref<MaterialListInfo[]>([]);
const handleSelection = (list: MaterialListInfo[]) => {
    selectIds.value = list.map((item: MaterialListInfo) => item.id!);
    materialList.value = list;
};

/**
 * 物料设置按钮事件
 */
const handleMaterialSetting = async () => {
    const res = await doGetMaterialSetting(false);
    const resUnit = await doGetMaterialUnit(false);
    if (res.data?.total === 0 && resUnit.data?.total === 0)
        Message.warning('请先维护物料设置中的物料分类和物料单位！');
    materialSettingRef.value.handleDialog();
};

/**
 * 生产类型下拉选项操作
 */
const handleSelectChange = (itemConfig: ItemConfig, row: MaterialListInfo) => {
    const modelKey = 'productionType'; // 当前控制动态切换必填项的字段

    // 只针对当前需动态切换的字段做逻辑处理
    if (itemConfig.modelKey === modelKey) {
        setItemRequired(row, modelKey);
    }
};

/**
 * 动态设置必填项
 */
const setItemRequired = (row: MaterialListInfo, modelKey: string, value?: string) => {
    const tableConfig = editTableConfig.value;
    const matchKey = ['fixedLeadTime', 'fixedLeadTimeBatch']; // 匹配动态修改必填项的字段名称
    const matchValue = value || ProductionType['HANDMADE'];

    tableConfig.items.forEach((item: ItemConfig) => {
        if (matchKey.includes(item.modelKey!)) {
            item.validProps!.required = row[modelKey] !== matchValue;
        }
    });
};

// 删除数据
const { handleDel, rowDel } = useDelRow(tableRef, selectIds, doDelMaterial);

/**
 * @: 编辑相关
 */
const baseEditRef = ref<EditRef>();
const handleEdit = (row: MaterialListInfo) => {
    baseEditRef.value?.open(row);
    setItemRequired(row, 'productionType');
    getMaterialList();
};

const handleEditSave = (data: MaterialListInfo) => {
    const params = handleDelKey(data, ['updateTime']);

    return doUpdateMaterial(params);
};

const getMaterialList = async () => {
    try {
        const res = await doGetMaterialSetting(false);

        if (res.data && res.data.records)
            materialSettingList.value = res.data.records.map((item: MaterialSetting) => ({
                value: item.id!,
                label: item.classificationName!
            }));
    } catch (error) {
        console.error(error);
    }
};

const { materialCode, setMaterialCode } = paramsStore();
const material = ref(materialCode);
const SearchConfig = computed(() => {
    searchConfig.items[1].default = material.value;
    setMaterialCode('');
    return searchConfig;
});

/**
 * 跳转至物料分类设置
 */
const selectRef = ref();
const toMarerialSetting = () => {
    // 数据更改后再做逻辑操作，防止页面闪烁问题
    nextTick(() => {
        selectRef.value.blur();
        baseEditRef.value?.close(); // 编辑
        handleMaterialSetting(); // 打开物料分类设置;
    });
};

const handleAdd = () => {
    handleAddData('materialsManagementAddData');
    tableRef.value?.clearSelection();
    router.push('/materialsManagement/add');
};

/**
 * 点击生产单位
 */
const selectProcedureId = ref(); // 记录当前选项 id 用于数据填充
const validProcedureId = ref(); // 记录当前校验 id 用于清除表格验证
const procedureId = ref(); //选中的数据id
const productUnit = ref(); // 生产单位
const procedureCodeVisible = ref(false);
const handleClickProcedureCode = (row: anyObj, id: number | string) => {
    selectProcedureId.value = row.id;
    validProcedureId.value = id;
    procedureId.value = row.productUnit ? row.processId : ''; // 防止清空生产单位，数据回显 bug
    productUnit.value = row.productUnit;
    procedureCodeVisible.value = true;
};

/**
 * 选择生产单位点击保存
 */
const handleProcedureCodeOk = (productUnits: MaterialSetting) => {
    const mapping = {
        productUnit: 'productUnit',
        purchaseUnit: 'purchaseUnit',
        processId: 'id',
        materialUnitId: 'id'
    } as const;
    type MappingKey = keyof typeof mapping;
    (Object.keys(mapping) as MappingKey[]).forEach(key => {
        baseEditRef.value!.formData[key] = productUnits[mapping[key]];
    });
};
</script>

<template>
    <q-page>
        <base-search
            ref="searchRef"
            :search-config="SearchConfig"
            :table-ref="tableRef"
            @refresh="material = ''"
        ></base-search>
        <base-table
            ref="tableRef"
            :tableConfig="tableConfig"
            :getDataFn="doGetMaterialList"
            :added-params="{ materialCode: material }"
            @selectionChange="handleSelection"
            @edit="handleEdit"
            @del="rowDel"
        >
            <template #tableHeadStart>
                <el-button type="primary" :icon="Plus" @click="handleAdd">新增</el-button>
                <el-button @click="handleMaterialSetting">物料设置</el-button>
            </template>
            <template #tableHeadEnd>
                <el-button
                    :icon="Delete"
                    :disabled="!selectIds.length"
                    class="m-r-16"
                    @click="handleDel(`选中${selectIds.length}行数据，删除后无法恢复，确认删除？`)"
                    >删除</el-button
                >
            </template>
            <template #slotManufacturingStrategy="{ row }">
                <span>{{ row.manufacturingStrategy }}</span>
            </template>
        </base-table>

        <!-- 编辑 -->
        <base-edit
            ref="baseEditRef"
            :edit-config="editTableConfig"
            :updateFn="handleEditSave"
            :table-ref="tableRef"
            @selectChange="handleSelectChange"
        >
            <template #materialClassificationSlot="{ row, item, validFn }">
                <el-select
                    ref="selectRef"
                    v-model="row[item.modelKey!]"
                    placeholder="请选择"
                    popper-class="push-select"
                    @focus="
                        (e: any) =>
                            validFn.handleFocus(e, row, {
                                config: item
                            })
                    "
                    @change="validFn.setValidErrorVisible(false)"
                    @blur="validFn.setValidErrorVisible(false)"
                >
                    <el-option
                        v-for="item in materialSettingList"
                        :key="item.value"
                        :label="item.label"
                        :value="item.value"
                    />
                    <template #footer>
                        <q-push-button @click="toMarerialSetting" />
                    </template>
                </el-select>
            </template>
            <template #productUnit="{ row, item }">
                <q-virtual-select
                    v-model="row.productUnit"
                    :closable="true"
                    placeholder="请选择"
                    @click="handleClickProcedureCode(row, item.validProps?.id!)"
                />
            </template>
            <template #purchaseUnit="{ row }">
                <el-input v-model="row.purchaseUnit" disabled />
            </template>
        </base-edit>

        <!-- 物料分类设置 -->
        <MaterialSettingModal ref="materialSettingRef" />
        <!-- 采购单位 -->
        <procurementUnit
            :id="procedureId"
            v-model:visible="procedureCodeVisible"
            :productUnit="productUnit"
            @ok="handleProcedureCodeOk"
        />
    </q-page>
</template>
